import numpy
class Variable:
    def __init__(self,x,dx):
        self.value=x
        self.dx=dx
    def __add__(self, other):
        if isinstance(other,Variable):
            value=self.value+other.value
            dx=self.dx+other.dx
            return Variable(value,dx)
        elif isinstance(other,float) or isinstance(other,int):
            value = self.value + other
            dx = self.dx
            return Variable(value, dx)
        else:
            raise ValueError("运算类型不支持")
    def __sub__(self, other):
        if isinstance(other,Variable):
            value=self.value-other.value
            dx=self.dx-other.dx
            return Variable(value,dx)
        elif isinstance(other,float) or isinstance(other,int):
            value = self.value - other
            dx = self.dx
            return Variable(value, dx)
        else:
            raise ValueError("运算类型不支持")
    def __rmul__(self, other):
        if isinstance(other,Variable):
            value=self.value*other.value
            dx=self.dx*other.value+self.value*other.dx
            return Variable(value,dx)
        elif isinstance(other,float) or isinstance(other,int):
            value = self.value*other
            dx = other*self.dx
            return Variable(value, dx)
        else:
            raise ValueError("运算类型不支持")
    def __mul__(self, other):
        if isinstance(other,Variable):
            value=self.value*other.value
            dx=self.dx*other.value+self.value*other.dx
            return Variable(value,dx)
        elif isinstance(other,float) or isinstance(other,int):
            value = self.value*other
            dx = other*self.dx
            return Variable(value, dx)
        else:
            raise ValueError("运算类型不支持")
    def __truediv__(self, other):
        if isinstance(other,Variable):
            value=self.value/other.value
            dx=(self.dx*other.value-self.value*other.dx)/other.value**2
            return Variable(value,dx)
        elif isinstance(other,float) or isinstance(other,int):
            value = self.value*other
            dx = other*self.dx
            return Variable(value, dx)
        else:
            raise ValueError("运算类型不支持")
    @staticmethod
    # def log(self):
    #     value=numpy.log(self.value)
    #     dx=1/self.value*self.dx
    #     return Variable(value, dx)
    def log(x):
        value = numpy.log(x.value)
        dx=1/x.value*x.dx
        return Variable(value, dx)
x=Variable(2,1)
y=Variable(1,0)
f=2*x/(x+1)+3*x
print(f.value)